<template>
  <div class="table_list_fix sku_table">
    <!-- 扩展性内容 -->
    <slot name="content_context" />
    <pl-table
      class="skus_table"
      ref="plTable"
      :border="border"
      size="mini"
      :row-height="rowHeight"
      use-virtual
      v-loading="loading"
      :data="dataSource"
      :height="getTableHeight()"
      :max-height="maxTableHeight"
      :header-cell-style="{ textAlign: 'center' }"
      :cell-style="{ textAlign: 'center' }"
      @selection-change="selectionChange"
      :data-changes-scroll-top="false"
      @sort-change="handleSortChange"
      :row-class-name="tableRowClassName"
      :thtd-beyond-hiding="headerBeyondHide"
      :row-key="handleRowKey"
      @row-click="handleRowClick"
      @row-dblclick="handleRowDbclick"
      @select="selectSelection"
    >
      <pl-table-column v-if="showSelectCol" fixed type="selection" width="55" :selectable="handleSelectable" :reserve-selection="!!handleRowKey" />
      <pl-table-column
        v-if="showTableIndex"
        type="index"
        width="50"
        fixed
        :label="'序号'"
      />
      <template v-for="column in columns">
        <pl-table-column
          v-if="!column.children"
          :key="column.key"
          :prop="column.key"
          :label="column.title"
          :property="column.key"
          :align="column.align"
          :min-width="column.width || defaultMinWidth"
          :fixed="column.fixed"
          :formatter="column.formatter"
          :sortable="column.sortable"
          :show-overflow-tooltip="!column.notShowTip"
        >
          <template v-if="column.required" slot="header">
            <span style="color: #ed4014">*</span><span>{{ column.title }}</span>
          </template>
          <template v-else-if="column.headTip" slot="header">
            <span>{{ column.title }}</span>
            <el-tooltip class="item" effect="dark" :content="column.headTip" placement="top">
              <i class="el-icon-question"></i>
            </el-tooltip>
          </template>
          <template v-else-if="column.headerRender" slot="header">
            <table-column :render="column.headerRender" />
          </template>
          <template v-if="column.render" v-slot="scope">
            <table-column
              :index="scope.$index"
              :row="scope.row"
              :col="scope.column"
              :render="column.render"
            />
          </template>
          <template v-else-if="column.key === 'action'" v-slot="scope">
            <el-button type="text" size="small" @click="handleCancelSelect(scope.row, scope.$index)">删除</el-button>
          </template>
          <template v-else-if="column.errorTip" v-slot="scope">
            <el-tooltip class="item" effect="dark" :content="scope.row[scope.column.property]" placement="top-start">
              <div class="costom_tooltip">{{ scope.row[scope.column.property] }}</div>
            </el-tooltip>
          </template>
          <!-- select -->
          <template v-else-if="column.type === 'select'" v-slot="scope">
            <el-select v-model="scope.row[scope.column.property]" placeholder="请选择">
              <el-option
                v-for="item in column.options"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </template>
          <!-- selectChange -->
          <template v-else-if="column.type === 'selectChange'" v-slot="scope">
            <el-select
              v-model="scope.row[scope.column.property]"
              placeholder="请选择"
              collapse-tags
              :disabled="column.disabled"
              :multiple="column.multiple"
              :clearable="column.clearable"
              :size="column.size"
              @change="(val) => { handleSelectChange({ row: scope.row, val, index: scope.$index, columnName: scope.column.property }) }"
            >
              <el-option
                v-for="item in column.options"
                :key="item.value"
                :label="item.label"
                :disabled="item.disabled"
                :value="item.value">
              </el-option>
            </el-select>
          </template>
          <!-- dropDownBox - 需要通过后端数据渲染表头情况下特殊处理的下拉框 -->
          <template v-else-if="column.type === 'dropDownBox'" v-slot="scope">
            <el-select v-if="scope.row[scope.column.property].allValueOptions.length !== 0" v-model="scope.row[scope.column.property].valueName" placeholder="请选择">
              <el-option
                v-for="item in scope.row[scope.column.property].allValueOptions"
                :key="item.optionValue"
                :label="item.optionHtml"
                :value="item.optionHtml">
              </el-option>
            </el-select>
          </template>
          <!-- inputSpecial -->
          <template v-else-if="column.type === 'inputSpecial'" v-slot="scope">
            <el-input
              v-model.trim="scope.row[scope.column.property].valueName"
              :maxlength="32"
            />
          </template>
          <!-- input -->
          <template v-else-if="column.type === 'input'" v-slot="scope">
            <el-input
              v-model.trim="scope.row[scope.column.property]"
              :maxlength="32"
            />
          </template>
          <!-- inputNoLimit -->
          <template v-else-if="column.type === 'inputNoLimit'" v-slot="scope">
            <el-input
              v-model.trim="scope.row[scope.column.property]"
              :maxlength="column.maxlength || ''"
              :show-word-limit="column.maxlength ? true : false"
              :placeholder="column.placeholder"
              :size="column.size"
              :suffix-icon="column.suffixIcon"
              @focus="() => { handleFocusInput(scope.row, scope.column.property, scope.$index) }"
              @change="val => { handleChangeInput(scope.row, scope.column.property, scope.$index, val) }"
            />
          </template>
          <!-- inputNum -->
          <template v-else-if="column.type === 'inputNum'" v-slot="scope">
            <el-input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :precision="column.precision"
              :min="column.min || 0"
              :max="column.max || 99999999"
            />
          </template>
          <!-- inputNumInt -->
          <template v-else-if="column.type === 'inputNumInt'" v-slot="scope">
            <el-input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :precision="0"
              :min="1"
              :max="99999999"
            />
          </template>
          <!-- inputNumNoLimit -->
          <template v-else-if="column.type === 'inputNumNoLimit'" v-slot="scope">
            <el-input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :max="99999999"
            />
          </template>
          <!-- inputNumChange -->
          <template v-else-if="column.type === 'inputNumChange'" v-slot="scope">
            <input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              @change="((val)=>{handleRowChange(scope.row, val, scope.column.property, scope.$index)})"
              :min="column.minVal || 0"
              :max="column.maxVal || 99999999"
              :precision="column.precision"
              :disabled="scope.row.disable"
              :controls="column.controls != false"
              :size="column.size"
            />
          </template>
          <template v-else-if="column.type === 'inputNumSpecial'" v-slot="scope">
            <input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :min="column.minVal || 0"
              :max="column.maxVal || 99999999"
              :precision="column.precision"
            />
          </template>
          <!-- inputNumSpecialChange -->
          <template v-else-if="column.type === 'inputNumSpecialChange'" v-slot="scope">
            <input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :min="0"
              :max="99999999"
              :precision="column.precision"
              @change="((val)=>{ handleRowSpecialChange({ row: scope.row, val, columnName: scope.column.property, index: scope.$index }) })"
            />
          </template>
          <!-- inputPrecisionMinMaxNumChange -->
          <template v-else-if="column.type === 'inputPrecisionMinMaxNumChange'" v-slot="scope">
            <input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              size="mini"
              :min="column.min || 0"
              :max="column.max || 99999999"
              :precision="column.precision || 0"
              :disabled="scope.row.inputDisabled"
              @change="((val)=>{handleRowChange(scope.row, val, scope.column.property, scope.$index)})"
            />
          </template>
          <template v-else-if="column.type == 'slot'" v-slot="scope">
            <slot :name="column.slotName || column.key" :data="{ row: scope.row, prop: scope.column.property, index: scope.$index }" />
          </template>
        </pl-table-column>
        <pl-table-column
          v-else
          :key="column.title"
          :label="column.title"
          :show-overflow-tooltip="true"
        >
          <template v-if="column.required" slot="header">
            <span style="color: #ed4014">*</span><span>{{ column.title }}</span>
          </template>
          <pl-table-column
            v-for="child in column.children"
            :key="child.key"
            :prop="child.key"
            :label="child.title"
            :property="child.key"
            :align="child.align"
            :width="child.width || 120"
            :formatter="child.formatter"
            :show-overflow-tooltip="true"
          >
            <template v-if="child.render" v-slot="scope">
              <table-column
                :index="scope.$index"
                :row="scope.row"
                :col="scope.column"
                :render="child.render"
              />
            </template>
            <!-- 辅计量进价 -->
            <!-- <template v-else-if="child.key === 'purchasePriceUpdate'" v-slot="scope">
              <el-input-number
                v-model="scope.row[scope.column.property]"
                controls-position="right"
                :min="0"
                :max="99999999"
                :precision="3"
                @change="((val)=>{handleRowChange(scope.row, val)})"
              />
            </template> -->
            <!-- select -->
            <template v-else-if="child.type === 'select'" v-slot="scope">
              <el-select v-model="scope.row[scope.column.property]" placeholder="请选择">
                <el-option
                  v-for="item in child.options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </template>
            <!-- selectSpecial -->
            <template v-else-if="child.type === 'selectSpecial'" v-slot="scope">
              <el-select v-model="scope.row[scope.column.property]" placeholder="请选择">
                <el-option
                  v-for="item in scope.row[child.options]"
                  :key="item.optionValue"
                  :label="item.optionHtml"
                  :value="item.optionValue">
                </el-option>
              </el-select>
            </template>
            <!-- dropDownBox - 需要通过后端数据渲染表头情况下特殊处理的下拉框 -->
            <template v-else-if="child.type === 'dropDownBox'" v-slot="scope">
              <el-select v-if="scope.row[scope.column.property].allValueOptions.length !== 0" v-model="scope.row[scope.column.property].valueNameUpdate" placeholder="请选择">
                <el-option
                  v-for="item in scope.row[scope.column.property].allValueOptions"
                  :key="item.optionValue"
                  :label="item.optionHtml"
                  :value="item.optionHtml">
                </el-option>
              </el-select>
            </template>
            <!-- classificationSelect - 归类专用下拉框 -->
            <template v-else-if="child.type === 'classificationSelect'" v-slot="scope">
              <el-select
                v-if="scope.row[child.optionsName].length !== 0"
                v-model="scope.row[scope.column.property]"
                placeholder="请选择"
                @visible-change="val => { handleClassificationSelect({ row: scope.row, val }) }"
                @change="val => { handleClassificationChange({ row: scope.row, val, optionsName: child.optionsName }) }"
              >
                <el-option
                  v-for="item in scope.row[child.optionsName]"
                  :key="item.uuid"
                  :label="item.classificationName"
                  :value="item.uuid">
                </el-option>
              </el-select>
            </template>
            <!-- inputSpecial -->
            <template v-else-if="child.type === 'inputSpecial'" v-slot="scope">
              <el-input
                v-model.trim="scope.row[scope.column.property].valueNameUpdate"
                :maxlength="32"
              />
            </template>
            <!-- input -->
            <template v-else-if="child.type === 'input'" v-slot="scope">
              <el-input
                v-model.trim="scope.row[scope.column.property]"
              />
            </template>
            <!-- inputNoLimit -->
            <template v-else-if="child.type === 'inputNoLimit'" v-slot="scope">
              <el-input
                v-model.trim="scope.row[scope.column.property]"
                :maxlength="child.maxlength || ''"
              />
            </template>
            <!-- inputChange -->
            <template v-else-if="child.type === 'inputChange'" v-slot="scope">
              <el-input
                v-model.trim="scope.row[scope.column.property]"
                @change="((val)=>{ handleRowInputModify({ row: scope.row, val, columnName: scope.column.property, index: scope.$index }) })"
                @input="((val)=>{ handleRegularCheck({ row: scope.row, val, regular: child.regular, columnName: scope.column.property, index: scope.$index }) })"
              />
            </template>
            <!-- inputNum -->
            <template v-else-if="child.type === 'inputNum'" v-slot="scope">
              <el-input-number
                v-model="scope.row[scope.column.property]"
                controls-position="right"
                :min="0"
                :max="99999999"
                :size="child.size"
                :controls="child.controls"
              />
            </template>
            <!-- inputNumChange -->
            <template v-else-if="child.type === 'inputNumChange'" v-slot="scope">
              <input-number
                v-model="scope.row[scope.column.property]"
                controls-position="right"
                :min="0"
                :max="99999999"
                @change="((val)=>{handleRowChange(scope.row, val)})"
                :precision="child.precision"
                :disabled="scope.row.disable"
                :controls="child.controls != false"
                :size="child.size"
              />
            </template>
            <!-- inputNumSpecial -->
            <template v-else-if="child.type === 'inputNumSpecial'" v-slot="scope">
              <input-number
                v-model="scope.row[scope.column.property]"
                controls-position="right"
                :min="child.minVal || 0"
                :max="99999999"
              />
            </template>
          </pl-table-column>
        </pl-table-column>
      </template>
      <pl-table-column
        align="center"
        v-if="showActionCol"
        :fixed="actionColFixed"
        :min-width="actionColWidth"
        :label="actionColLabel">
        <template slot-scope="scope">
          <table-column
            :index="scope.$index"
            :row="scope.row"
            :col="scope.column"
            :render="actionRender"
          />
        </template>
      </pl-table-column>
    </pl-table>
    <!-- table表格 -->

    <!-- 分页部分 -->
    <div v-if="showPagination" class="pagination-container">
      <el-pagination
        :total="total"
        :current-page="pagination.pageNum"
        :page-sizes="pageSizes"
        :page-size="pagination.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        @current-change="handlePageChange"
        @size-change="handlePageSize"
      />
    </div>
    <div v-if="!showPagination && showTotal" class="total-container">
      <span class="total-num">共 {{ dataSource.length || 0 }} 条</span>
    </div>
  </div>
</template>

<script>
import tableColumn from './tableColumn';
import inputNumber from '@/components/inputNumber/inputNumber'
import { handleSortCompare } from '@/utils/bizUtils'

export default {
  name: 'BasicList',
  components: {
    tableColumn,
    inputNumber
  },
  props: {
    dataSource: {
      type: Array,
      default () {
        return [];
      },
    },
    columns: {
      type: Array,
      default () {
        return [];
      },
    },
    actionColFixed: {
      type: [Boolean, String],
      default: 'right',
    },
    showActionCol: {
      type: Boolean,
      default: false,
    },
    tableHeight: {
      type: Number,
      default: 500,
    },
    maxTableHeight: { // 表格最大高度
      type: Number,
      default: null
    },
    actionColWidth: {
      type: Number,
      default: 100,
    },
    actionColLabel: {
      type: String,
      default: '操作',
    },
    actionRender: {
      type: Function,
      default: () => {},
    },
    showSelectCol: {
      type: Boolean,
      default: false,
    },
    border: {
      type: Boolean,
      default: true,
    },
    loading: {
      type: Boolean,
      default: false,
    },
    showPagination: {
      type: Boolean,
      default: false,
    },
    showTotal: {
      type: Boolean,
      default: true,
    },
    pagination: {
      type: Object,
      default () {
        return {};
      },
    },
    total: {
      type: Number,
      default: 0,
    },
    selectionChange: {
      type: Function,
      default: () => {},
    },
    selectSelection: {
      type: Function,
      default: () => {},
    },
    showTableIndex: {
      type: Boolean,
      default: false
    },
    checkSelectable: {
      type: Function
    },
    defaultMinWidth: {
      type: [Number, String]
    },
    pageSizes: {
      type: Array,
      default () {
        return [50, 100, 500, 1000];
      }
    },
    // 是否自定义排序方法
    isCustomSort: {
      type: Boolean,
      default: false
    },
    // 表格背景色设置
    tableRowClassName: {
      type: Function,
      default: () => {},
    },
    // 表头超出长度是否隐藏
    headerBeyondHide: {
      type: Boolean,
      default: true
    },
    // 表格行高度
    rowHeight: {
      type: Number,
      default: 45
    },
    // 行数据的 Key，有此方法时启用勾选列的reserve-selection属性值
    handleRowKey: {
      type: Function
    }
  },

  data () {
    return {
      multipleSelection: [],
    };
  },
  mounted () {
    this.$nextTick(() => {
      this.$emit('toggleRowSelection', this.$refs.plTable);
    });
  },
  methods: {
    getTableHeight () {
      return this.maxTableHeight ? null : this.tableHeight;
    },
    /* 正则校验方法，输入不符合条件的内容给设成空串 */
    handleRegularCheck (data) {
      let { row, val, regular, columnName } = data
      if (!regular) { return }
      let replaceVal = _.replace(val, regular, '')
      row[columnName] = replaceVal
    },
    handleRowInputModify (data) {
      this.$emit('handleRowInputModify', data)
    },
    /* 特殊处理的inputNumChange方法 */
    handleRowSpecialChange (data) {
      this.$emit('handleRowSpecialChange', data)
    },
    /* 下拉框选择需要调用变化的方法 */
    handleSelectChange (data) {
      this.$emit('handleSelectChange', data)
    },
    handleRowChange (row, val, property, index) {
      this.$emit('handleRowChange', row, val, property, index);
    },
    handleCancelSelect (row, index) {
      this.$emit('handleCancelSelect', { row, index });
    },
    handlePageChange (current) {
      this.$emit('pageChange', current);
    },
    handlePageSize (length) {
      this.$emit('pageSizeSelect', length);
    },
    /* 表格checkbox禁用与否状态 */
    handleSelectable (row, index) {
      /*
        返回true，表格可勾选
        返回false，表格不可勾选
      */
      if (!this.checkSelectable) { // 如果没有表格勾选状态判断方法，就默认可以勾选
        return true;
      }
      return this.checkSelectable({ row });
    },
    // 归类选择的事件
    handleClassificationSelect ({ val, row }) {
      if (val) {
        this.$emit('visibleChange', row);
      }
    },
    // 确定选择的归类
    handleClassificationChange ({ val, row, optionsName }) {
      const target = row[optionsName].find(item => item.uuid === val);
      this.$emit('selectChange', { row, target });
    },
    // 排序
    handleSortChange ({ prop, order }) {
      if (!this.isCustomSort) {
        this.dataSource.sort(handleSortCompare(prop, order))
      } else {
        this.$emit('customSortChange', { prop, order })
      }
    },
    // input focus事件
    handleFocusInput (row, prop, index) {
      this.$emit('input-focus', { row, prop, index })
    },
    handleChangeInput (row, prop, index, val) {
      this.$emit('input-change', { row, prop, index, val })
    },
    // 单击行
    handleRowClick (row, column, event) {
      this.$emit('rowClick', { row, column, event })
    },
    // 双击行
    handleRowDbclick (row, column, event) {
      this.$emit('rowDblclick', { row, column, event })
    }
  },
};
</script>

<style lang="less" scoped>
/deep/ .el-table thead.is-group th {
  background: #fff;
}
.sku_table {
  /deep/.el-table td, .el-table th {
    line-height: normal;
    height: 45px;
  }
}
.pagination-container {
    text-align: right;
    padding-right: 20px;
    margin-top: 20px;
    margin-bottom: 10px;
}
.total-num {
  margin-top: 5px;
  float: right;
}

.skus_table {
  margin-top: 6px;
}
/deep/.plTableBox .el-table .warning-row {
  background: oldlace;
}

/deep/.plTableBox .el-table .success-row {
  background: #f0f9eb;
}

/deep/.plTableBox .el-table .error-row {
  background: #f7c5c5;
}
</style>
